﻿/****************************** Module Header ******************************\
 * Module Name:  TemplateTextHelper.cs
 * Module Version:  1.0.0 (2012-9-9)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * 配合TemplateText自定义控件，用于服务端模板处理。
 * (困扰多时的Cat开发模式模板灵活性以及效能的问题终于解决了，佩服俺自己哈！)
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace UCL
{
    /// <summary>
    /// 模板助理类
    /// </summary>
    public class TemplateTextHelper
    {
        /// <summary>
        /// 原模板内容
        /// <para>如：&lt;h1&gt;{Title}&lt;/h1&gt;&lt;div&gt;{Content}&lt;/div&gt;</para>
        /// </summary>
        public string SourceText { get; set; }

        /// <summary>
        /// 占位符模板内容
        /// <para>如：&lt;h1&gt;{0}&lt;/h1&gt;&lt;div&gt;{1}&lt;/div&gt;</para>
        /// </summary>
        public string FormatText { get; set; }

        /// <summary>
        /// 模板变量存储器
        /// </summary>
        private Dictionary<string, object> dictVars;

        /// <summary>
        /// 当前操作中的模板变量
        /// </summary>
        private string currentvar;

        /// <summary>
        /// 外部循环计数器
        /// </summary>
        public int Counter { get; set; }

        private string formater;

        /// <summary>
        /// 构造方法
        /// <para>如：&lt;h1&gt;{Title}&lt;/h1&gt;&lt;div&gt;{Content}&lt;/div&gt;</para>
        /// </summary>
        /// <param name="tpl"></param>
        public TemplateTextHelper(string tpl, string formater = @"{\w+}")
        {
            this.formater = formater;
            this.dictVars = new Dictionary<string, object>();
            this.SourceText = tpl;
            this.ParseTemplateVars(tpl);
            this.FormatText = ToStringFormatTemplateText(tpl, this.dictVars);
            this.Counter = 0;
        }

        /// <summary>
        /// 是否有存在指定的变量名称
        /// </summary>
        /// <param name="varname"></param>
        /// <returns></returns>
        public bool HasVar(string varname)
        {
            if (this.dictVars.ContainsKey(varname))
            {
                this.currentvar = varname;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 设置当前变量名称的值
        /// </summary>
        /// <param name="value"></param>
        public void SetValue(object value)
        {
            if (value == null) return;
            this.dictVars[this.currentvar] = value;
        }

        /// <summary>
        /// 获取模板中所有变量名称的集合
        /// </summary>
        /// <param name="tpl"></param>
        /// <returns></returns>
        private void ParseTemplateVars(string tpl)
        {
            Regex re = new System.Text.RegularExpressions.Regex(formater);
            foreach (Match m in re.Matches(tpl))
            {
                if (!this.dictVars.ContainsKey(m.Value)) dictVars.Add(m.Value, string.Empty);
            }
        }

        /// <summary>
        /// 将名称变量模板转换为占位符变量模板
        /// </summary>
        /// <param name="tpl"></param>
        /// <param name="dict"></param>
        /// <returns></returns>
        private string ToStringFormatTemplateText(string tpl, Dictionary<string, object> dict)
        {
            int i = 0;
            Regex re2;
            foreach (string s in dict.Keys)
            {
                re2 = new Regex(s);
                tpl = re2.Replace(tpl, string.Format("{{{0}}}", i));
                i++;
            }
            return tpl;
        }

        /// <summary>
        /// 输出替换成真实值的模板内容
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            this.Counter++;
            return string.Format(this.FormatText, this.dictVars.Values.ToArray());
        }
    }
}
